package com.ruoyi.door.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * 房产相关计算工具类
 * 
 * @author ruoyi
 */
public class HouseUtil {
    
    /**
     * 计算房产余额
     * 余额 = (截止月份 - 开始月份) * 月租
     * 
     * @param startDate 开始日期
     * @param endDate 截止日期
     * @param monthPrice 月租金
     * @return 余额
     */
    public static BigDecimal calculateBalance(Date startDate, Date endDate, BigDecimal monthPrice) {
        if (startDate == null || endDate == null || monthPrice == null) {
            return BigDecimal.ZERO;
        }
        
        // 转换为LocalDate进行计算
        LocalDate start = convertToLocalDate(startDate);
        LocalDate end = convertToLocalDate(endDate);
        
        // 计算月份差
        long monthsBetween = ChronoUnit.MONTHS.between(
            YearMonth.from(start), 
            YearMonth.from(end)
        );
        
        // 计算余额 = 月份差 * 月租
        return monthPrice.multiply(BigDecimal.valueOf(monthsBetween))
                        .setScale(2, RoundingMode.HALF_UP);
    }
    
    /**
     * 根据余额和月租计算开始月份
     * 开始月份 = 截止月份 + (余额 ÷ 月租)
     * 
     * @param endDate 截止日期
     * @param balance 余额
     * @param monthPrice 月租金
     * @return 开始日期
     */
    public static Date calculateStartDate(Date endDate, BigDecimal balance, BigDecimal monthPrice) {
        if (endDate == null || balance == null || monthPrice == null || monthPrice.compareTo(BigDecimal.ZERO) == 0) {
            return endDate;
        }
        
        // 转换为LocalDate进行计算
        LocalDate end = convertToLocalDate(endDate);
        
        // 计算月份数 = 余额 ÷ 月租
        BigDecimal monthsDecimal = balance.divide(monthPrice, 0, RoundingMode.HALF_UP);
        long months = monthsDecimal.longValue();
        
        // 计算开始日期 = 截止日期 - 月份数
        LocalDate start = end.plusMonths(months+1);
        
        // 转换回Date
        return convertToDate(start);
    }
    
    /**
     * Date转LocalDate
     */
    private static LocalDate convertToLocalDate(Date date) {
        return new java.sql.Date(date.getTime()).toLocalDate();
    }
    
    /**
     * LocalDate转Date
     */
    private static Date convertToDate(LocalDate localDate) {
        // 转换为java.util.Date而不是java.sql.Date，避免ORM框架兼容性问题
        return Date.from(localDate.atStartOfDay().atZone(java.time.ZoneId.systemDefault()).toInstant());
    }
    
    /**
     * 根据余额和月租计算到期日期（基准日期为当前月份的第一天）
     * 如果余额为0，到期日期为当前月份的第一天
     * 如果余额为10，月租为10，到期日期为下个月的第一天
     * 
     * @param balance 余额
     * @param monthPrice 月租金
     * @return 到期日期
     */
    public static Date calculateEndDateFromBaseDate(BigDecimal balance, BigDecimal monthPrice) {
        if (balance == null || monthPrice == null || monthPrice.compareTo(BigDecimal.ZERO) <= 0) {
            // 默认返回当前月份的第一天
            return null;
        }
        
        // 基准日期：当前月份的第一天
        LocalDate now = LocalDate.now();
        LocalDate baseDate = LocalDate.of(now.getYear(), now.getMonth(), 1);
        
        // 计算月份数 = 余额 ÷ 月租
        BigDecimal monthsDecimal = balance.divide(monthPrice, 0, RoundingMode.HALF_UP);
        long months = monthsDecimal.longValue();
        
        // 计算到期日期 = 基准日期 + 月份数
        LocalDate end = baseDate.plusMonths(months);
        System.out.println("end:"+end);
        // 转换回Date
        return convertToDate(end);
    }
}
